/*********************************************************
          File Name:test_shared_ptr.cpp
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Tue 15 Dec 2015 08:12:09 PM CST
**********************************************************/

#include <iostream>
#include "shared_ptr.h"

using namespace std;

struct Point
{
        int x;
        int y;
};

int main()
{
        nm::shared_ptr<Point> point(new Point);

        cout << "point.unique() " << std::boolalpha << point.unique() << endl;
        cout << "ref_count = " << point.use_count() << endl;

        point->x = 1;
        point->y = 2;

        cout << point->x << "\t" << point->y << endl;

        {
                auto x = point;
        }

        auto y = point;
        auto z(y);

        cout << "ref_count = " << z.use_count() << endl;
        cout << "ref_count = " << y.use_count() << endl;
        cout << "z.unique() " << std::boolalpha << z.unique() << endl;
        cout << "before shared_ptr::reset()" << endl;

        if(z)
                cout << "valid" << endl;
        else
                cout << "invalid" << endl;

        cout << "after shared_ptr::reset()" << endl;

        if(z)
                cout << "valid" << endl;
        else
                cout << "invalid" << endl;


        nm::shared_ptr<int> non;

        cout << "non.unique() " << std::boolalpha << non.unique() << endl;
        cout << "non.ref_count = " << non.use_count() << endl;
        auto tmp = non;
        cout << "tmp.unique() " << std::boolalpha << tmp.unique() << endl;
        cout << "tmp.ref_count = " << tmp.use_count() << endl;

        int *null = nullptr;
        nm::shared_ptr<int> null_ptr(null);

        if(null_ptr)
                cout << "valid" << endl;
        else
                cout << "invalid" << endl;

        nm::shared_ptr<int> arr(new int[10], 
                        [](int *p)
                        {
                                delete [] p;
                                cout << "Ok." << endl;
                        });

        return 0;
}
